<script>
    // 关于程序集卸载

            /*
                        在C#中，卸载程序集(Assembly) 并不是一个直接且简单的操作，

                        因为 .net 运行时 (CLR) 对程序集的管理有特定机制、
                
                        以下是关于程序集卸载的关键只是和实现方式：
            */

            /*
                一、核心限制

                        1、默认情况下，已加载到 "默认应用程序域(AppDomain)" 的程序集是无法直接卸载的。

                               这是因为程序集一旦被加载，就会与加载它的应用程序域绑定。

                        2、只有通过 "创建新的应用程序域(AppDomain)" 来加载程序集，然后卸载整个应用程序与的方式，才能间接实现程序集的卸载。

            */

            /*
                二、实现方法： （使用应用程序域实现）

                                    using System;
                                    using System.Reflection;

                                    public class AssemblyUnloader : MarshalByRefObject
                                    {
                                        // 加载程序集的方法
                                        public void LoadAssembly(string assemblyPath)
                                        {
                                            try
                                            {
                                                // 加载程序集
                                                Assembly.LoadFrom(assemblyPath);
                                                Console.WriteLine($"程序集 {assemblyPath} 已加载");
                                            }
                                            catch (Exception ex)
                                            {
                                                Console.WriteLine($"加载失败: {ex.Message}");
                                            }
                                        }
                                    }

                                    class Program
                                    {
                                        static void Main(string[] args)
                                        {
                                            // 创建新的应用程序域
                                            AppDomainSetup setup = new AppDomainSetup();
                                            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
                                            AppDomain newDomain = AppDomain.CreateDomain("TempDomain", null, setup);

                                            try
                                            {
                                                // 在新应用程序域中加载并使用程序集
                                                AssemblyUnloader unloader = (AssemblyUnloader)newDomain.CreateInstanceAndUnwrap(
                                                    typeof(AssemblyUnloader).Assembly.FullName,
                                                    typeof(AssemblyUnloader).FullName);

                                                // 加载目标程序集
                                                unloader.LoadAssembly(@"C:\Path\To\Your\Assembly.dll");
                                            }
                                            finally
                                            {
                                                // 卸载整个应用程序域，从而卸载其中的程序集
                                                AppDomain.Unload(newDomain);
                                                Console.WriteLine("应用程序域已卸载，程序集随之卸载");
                                            }
                                        }
                                    }
            */

            /*
                三、关键说明

                        1、工作原理：

                                ①、创建独立的应用程序域(AppDomain) 来加载目标程序集

                                ②、当不再需要时，通过 AppDomain.Unload() 方法卸载整个应用程序域。

                                ③、卸载应用程序域会释放该域中所有加载的程序集资源。


                        2、注意事项：

                                ①、应用程序域通信需要使用 MarshalByRefObject

                                ②、卸载应用程序域是一个异步操作，CLR 会尽力完成，但不保证立即完成。

                                ③、对于 .NER Core/ .NET 5+, ApppDomain类仍然存在，但是功能受限，
                                
                                            推荐使用更现代的AssemblyLoadContext 

                        3、.net Core / .net 5+ 中的替代方案：

                                使用 AssemblyLoadContext(ALC) 类来加载和卸载程序集。

                                    // 需要引用 System.Runtime.Loader 命名空间
                                    var alc = new AssemblyLoadContext(null, true); // 第二个参数设为true表示可卸载
                                    var assembly = alc.LoadFromAssemblyPath(@"C:\Path\To\Your\Assembly.dll");
                                    // 使用程序集...
                                    alc.Unload(); // 卸载
            */

           /*
                四、总结

                        在C# 中无法直接卸载单个程序集，必须通过卸载其所在的  应用程序域 (或 AssemblyLoadContext )来间接实现。

                        这种设计师为了保证CLR内存管理的稳定和安全性。
           */
</script>